/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.context.support;

import java.util.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.lang.Nullable;

/**
 * Delegate for AbstractApplicationContext's post-processor handling.
 *
 * @author Juergen Hoeller
 * @since 4.0
 */
final class PostProcessorRegistrationDelegate {

	private PostProcessorRegistrationDelegate() {
	}

	/**
	 *
	 * 调用顺序
	 * 1.先执行传进来的集合beanFactoryPostProcessors
	 * 2.处理实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
	 * 3.处理实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor
	 * 4.处理剩余的普通 BeanDefinitionRegistryPostProcessor
	 * 5.处理普通的 BeanFactoryPostProcessor
	 *
	 * 执行 BeanFactoryPostProcessor 的调用流程
	 *
	 * @param beanFactory 可配置的 BeanFactory
	 * @param beanFactoryPostProcessors 需要执行的 BeanFactoryPostProcessor 列表
	 */
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// 用于记录已经处理过的后置处理器名称
		Set<String> processedBeans = new HashSet<>();

		// 检查 BeanFactory 是否同时是 BeanDefinitionRegistry 的实现
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

			// 普通 BeanFactoryPostProcessor 列表
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// BeanDefinitionRegistryPostProcessor 专用列表
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();


			//先处理传进来的集合
			// 第一步：处理手动注册的后置处理器
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					// 如果是 BeanDefinitionRegistryPostProcessor
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					// 先执行对 BeanDefinition 的注册处理
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					// 普通 BeanFactoryPostProcessor 先暂存
					regularPostProcessors.add(postProcessor);
				}
			}

			// 当前正在处理的后置处理器列表
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// 第二步：处理实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);  // 记录已处理
				}
			}

			// 排序后执行
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// 第三步：处理实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// 第四步：处理剩余的普通 BeanDefinitionRegistryPostProcessor
			//他有一个标识，只要是还进入了判断，说明还可能有BeanDefinitionRegistryPostProcessor类型的类
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;  // 可能有新的后置处理器被注册，需要再次检查
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// 第五步：执行所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			// 执行普通 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}
		else {
			// 如果不是 BeanDefinitionRegistry，直接执行 postProcessBeanFactory 方法
			//这里执行属于自定义的BeanFactoryPostProcessor，
			//else过后执行的是    容器中检测到的bean	@Component注解的处理器
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// 第六步：处理普通的 BeanFactoryPostProcessor
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// 按优先级分类
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// 跳过已经处理过的
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 按优先级顺序执行
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 处理 Ordered 接口的实现
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 最后处理普通的后置处理器
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// 清除缓存的合并后的 BeanDefinition，因为后置处理器可能修改了原始元数据
		beanFactory.clearMetadataCache();
	}


	/**
	 * 注册容器中所有的 BeanPostProcessor。
	 *
	 * 该方法负责：
	 * 1. 获取所有 BeanPostProcessor 类型的 bean 名称
	 * 2. 添加日志记录用的 BeanPostProcessorChecker
	 * 3. 按优先级分类处理器（PriorityOrdered > Ordered > 普通）
	 * 4. 按优先级顺序注册处理器
	 * 5. 特殊处理内部 MergedBeanDefinitionPostProcessor
	 * 6. 确保 ApplicationListenerDetector 最后执行
	 *
	 * @param beanFactory 可配置的 BeanFactory，用于获取和注册 BeanPostProcessor
	 * @param applicationContext 关联的 ApplicationContext，用于传递上下文信息
	 */
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		// 获取所有实现 BeanPostProcessor 接口的 bean 名称（不包含预实例化的 bean）
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 计算目标后置处理器总数（当前数量 + 将要添加的数量 + 1个Checker）
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;

		// 添加日志记录器 BeanPostProcessorChecker，用于在 bean 创建过程中记录调试信息
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 创建分类集合：
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();  // 实现 PriorityOrdered 接口的处理器（最高优先级）
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();         // 内部 MergedBeanDefinitionPostProcessor 处理器
		List<String> orderedPostProcessorNames = new ArrayList<>();                 // 实现 Ordered 接口的处理器名称（中等优先级）
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();              // 普通处理器名称（无排序）

		// 第一步：遍历所有后置处理器名称，按优先级分类
		for (String ppName : postProcessorNames) {
			// 1. 检查是否实现 PriorityOrdered（最高优先级）
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 实例化并添加到优先级列表
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				// 如果是 MergedBeanDefinitionPostProcessor，额外添加到内部处理器列表
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			// 2. 检查是否实现 Ordered（中等优先级）
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);  // 仅记录名称，稍后实例化
			}
			// 3. 普通处理器（无排序接口）
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 第二步：处理最高优先级（PriorityOrdered）处理器
		// 按优先级排序（通过 OrderComparator）
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 注册到 BeanFactory（添加到内部处理器列表）
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 第三步：处理中等优先级（Ordered）处理器
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			// 收集内部处理器
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		// 排序并注册
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 第四步：处理普通处理器（无优先级接口）
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			// 收集内部处理器
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		// 直接注册（无需排序）
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 第五步：重新注册所有内部 MergedBeanDefinitionPostProcessor
		// 目的：确保这些处理器在处理器链中处于正确位置（在代理生成器等处理器之后）
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 第六步：手动注册 ApplicationListenerDetector
		// 作用：检测实现了 ApplicationListener 接口的 bean 并注册到上下文
		// 必须最后执行：确保能捕获到所有 bean 的初始化完成事件
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}
	/**
	 * 对后置处理器进行排序
	 */
	private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
		Comparator<Object> comparatorToUse = null;
		if (beanFactory instanceof DefaultListableBeanFactory) {
			// 使用 BeanFactory 的依赖比较器
			comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
		}
		if (comparatorToUse == null) {
			// 默认使用 OrderComparator
			comparatorToUse = OrderComparator.INSTANCE;
		}
		postProcessors.sort(comparatorToUse);
	}

	//BeanFactoryPostProcessor的方法是postProcessorBeanFactory
	//Bean
	/**
	 * 执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法
	 */
	private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}
	/**
	 * 执行 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
	 */
	private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanFactory(beanFactory);
		}
	}


	/**
	 * 注册 BeanPostProcessor
	 */
	private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}


	/**
	 * 用于检查 BeanPostProcessor 的处理器
	 * 当在 BeanPostProcessor 初始化期间创建 bean 时记录信息消息
	 */
	private static final class BeanPostProcessorChecker implements BeanPostProcessor {
		private static final Log logger = LogFactory.getLog(BeanPostProcessorChecker.class);

		private final ConfigurableListableBeanFactory beanFactory;
		private final int beanPostProcessorTargetCount;

		public BeanPostProcessorChecker(ConfigurableListableBeanFactory beanFactory, int beanPostProcessorTargetCount) {
			this.beanFactory = beanFactory;
			this.beanPostProcessorTargetCount = beanPostProcessorTargetCount;
		}

		@Override
		public Object postProcessBeforeInitialization(Object bean, String beanName) {
			return bean;  // 不做任何处理
		}

		@Override
		public Object postProcessAfterInitialization(Object bean, String beanName) {
			// 如果不是 BeanPostProcessor 且不是基础设施 bean，并且 BeanPostProcessor 还没有全部注册完成
			if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
					this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
				if (logger.isInfoEnabled()) {
					logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
							"] is not eligible for getting processed by all BeanPostProcessors " +
							"(for example: not eligible for auto-proxying)");
				}
			}
			return bean;
		}

		// 检查是否是基础设施 bean
		private boolean isInfrastructureBean(@Nullable String beanName) {
			if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) {
				BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName);
				return (bd.getRole() == RootBeanDefinition.ROLE_INFRASTRUCTURE);
			}
			return false;
		}
	}

}
